/*******************************************************************************
 * File name:     sdram.c
 * Description:
 * Project:       _htx
 * Target:        LPC2478
 * Compiler:      arm-none-eabi-gcc
 * Date:          10-11-2010
 * Author:        PawelKobylecki
 * Based on:      ---
 ******************************************************************************/
/*==============================================================================
 Includes
==============================================================================*/
#include <stdio.h>
#include "typedef.h"
#include "LPC24xx.h"    /* LPC23xx/24xx Peripheral Registers   */
#include "sdram.h"

/*==============================================================================
 Defines
==============================================================================*/
#define SDRAM_BASE_ADDR       0xA0000000


#define SYS_FREQ  72

#if   SYS_FREQ == (72)
#define SDRAM_PERIOD          13.8  // 72MHz
#elif   SYS_FREQ == (57)
#define SDRAM_PERIOD          17.4  // 57.6MHz
#elif SYS_FREQ == (48)
#define SDRAM_PERIOD          20.8  // 48MHz
#elif SYS_FREQ == (36)
#define SDRAM_PERIOD          27.8  // 36MHz
#elif SYS_FREQ == (24)
#define SDRAM_PERIOD          41.7  // 24MHz
#else
#error Frequency not defined
#endif

/* macro is defined to transfer timing parameters from 'ns' to 'CCLK' */
#define P2C(Period)           (((Period<SDRAM_PERIOD)?0:(uint32)((float)Period/SDRAM_PERIOD))+1)


//Deklaraja parametrow pamieci SDRAM IS42S16160D7TLI(projekt HT)
#define SDRAM_REFRESH         7813
#define SDRAM_TRP             20//ns
#define SDRAM_TRAS            45//45ns
#define SDRAM_TAPR            3
#define SDRAM_TDAL            5
#define SDRAM_TWR             2
#define SDRAM_TRC             68
#define SDRAM_TRFC            68
#define SDRAM_TXSR            75
#define SDRAM_TRRD            14
#define SDRAM_TMRD            14


/*==============================================================================
 Globals
==============================================================================*/

/*==============================================================================
 Static function prototypes
==============================================================================*/

/*==============================================================================
 Static ISR prototypes
==============================================================================*/

/*==============================================================================
 Global function definitions
==============================================================================*/

/*------------------------------------------------------------------------------
 function name:   sdramInit
 description:  EMC SDRAM initialization
 parameters:   none
 returned value: none
------------------------------------------------------------------------------*/
void sdram_init (void)
{
   volatile uint32 i, dummy;

//======================================Step 1: EMC GPIO configuration===============================================

   PINSEL5 &= 0x00FCFCC0; //BIN32(00000000,11111100,11111100,11000000);
   PINSEL5 |= 0x55010115; //BIN32(01010101,00000001,00000001,00010101);
   PINMODE5&= 0x00FCFCC0; //BIN32(00000000,11111100,11111100,11000000);
   PINMODE5|= 0xAA02022A; //BIN32(10101010,00000010,00000010,00101010);
   PINSEL6  = 0x55555555; //BIN32(01010101,01010101,01010101,01010101);
   PINMODE6 = 0xAAAAAAAA; //BIN32(10101010,10101010,10101010,10101010);
   PINSEL7  = 0x55555555; //BIN32(01010101,01010101,01010101,01010101);
   PINMODE7 = 0xAAAAAAAA; //BIN32(10101010,10101010,10101010,10101010);
   PINSEL8 &= 0xC0000000; //BIN32(11000000,00000000,00000000,00000000);
   PINSEL8 |= 0x15555555; //BIN32(00010101,01010101,01010101,01010101);
   PINMODE8&= 0xC0000000; //BIN32(11000000,00000000,00000000,00000000);
   PINMODE8|= 0x2AAAAAAA; //BIN32(00101010,10101010,10101010,10101010);
   PINSEL9 &= 0xFFF3FFFF; //BIN32(11111111,11110011,11111111,11111111);
   PINSEL9 |= 0x00040000; //BIN32(00000000,00000100,00000000,00000000);
   PINMODE9&= 0xFFF3FFFF; //BIN32(11111111,11110011,11111111,11111111);
   PINMODE9|= 0x00080000; //BIN32(00000000,00001000,00000000,00000000);

   PINSEL5 |= (1 << 24)|(1 << 26)|(1 << 28)|(1 << 30);

//======================================Step 2: enable EMC and set EMC parameters====================================== /AN10771_1 str.11/

    // Enable EMC clock
    PCONP           |= 0x800;       //enable EMC power
    EMC_CTRL         = 1;           //enable EMC
    EMC_DYN_RD_CFG   = 1;           //Configures the dynamic memory read strategy(Command delayed strategy)
    EMC_DYN_RASCAS0 |= (2 << 8);    // CAS Two CCLK cycles (POR reset value)
    //EMC_DYN_RASCAS0 |= (3 << 8);  // CAS Three CCLK cycles (POR reset value)
    EMC_DYN_RASCAS0 |= (3 << 0);    // RAS Three CCLK cycles (POR reset value)
    //EMC_DYN_RASCAS0 |= (2 << 0);  // RAS Two CCLK cycles (POR reset value)

    EMC_DYN_RP   = P2C(SDRAM_TRP);  // command period clock cycles
    EMC_DYN_RAS  = P2C(SDRAM_TRAS); // RAS command period clock cycles
    EMC_DYN_SREX = P2C(SDRAM_TXSR); // self-refresh period clock cycles
    EMC_DYN_APR  = SDRAM_TAPR;      // data out to active clock cycles
    EMC_DYN_DAL  = SDRAM_TDAL;      // data in to active clock cycles
    EMC_DYN_WR   = SDRAM_TWR;       // write recovery clock cycles
    EMC_DYN_RC   = P2C(SDRAM_TRC);  // active to Active cmd clock cycles
    EMC_DYN_RFC  = P2C(SDRAM_TRFC); // auto-refresh clock cycles
    EMC_DYN_XSR  = P2C(SDRAM_TXSR); // exit self-refresh clock cycles
    EMC_DYN_RRD  = P2C(SDRAM_TRRD); // active bank A->B clock cycles
    EMC_DYN_MRD  = P2C(SDRAM_TMRD); // load Mode to Active cmd: 3(n+1) clock cycles
    EMC_DYN_CFG0 = (1 << 14)        // 32 bit external bus, 13 row, 9 - col, SDRAM
                 | (0 << 12)
                 | (3 <<  9)
                 | (1 <<  7)
                 ;
//======================================Step 3: perform SDRAM initialization====================================== /AN10771_1 str.11/

   // JEDEC General SDRAM Initialization Sequence
   // DELAY to allow power and clocks to stabilize ~100 us

   //**************SDRAM NOP command**************
    EMC_DYN_CTRL = 0x0183;                   //Issue SDRAM NOP (no operation) command ; CLKOUT runs continuously;All clock enables are driven HIGH continuously
    for (i = 0; i < 200*30; ++i);            //delay 200ms

   //**************SDRAM PALL command**************
    EMC_DYN_CTRL = 0x00000103;               //Issue PALL command
    EMC_DYN_RFSH = 1;                        //Indicates 1X16 CCLKs between SDRAM refresh cycles.
    for (i = 0; i < 128; ++i);               // > 128 clk.
    EMC_DYN_RFSH = P2C(SDRAM_REFRESH) >> 4;  //Indicates SDRAM_REFRESH time between SDRAM refresh cycles.

   //**************SDRAM MODE command**************
    EMC_DYN_CTRL|=0x80; EMC_DYN_CTRL&=0xFFFFFEFF;   //Issue SDRAM MODE command.
    //SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
    //COL=# of column bits (here: 9)
    //TBW=total bus width, 1=16 bits, 2=32 bits (here: 2)
    //BANK=# of bank select bits (here: 2)
    // --Formula courtesy of Rolf Meeser
    // Burst 4, Sequential, CAS-3; For 32bit bus configuration burst lenght should be 4
    dummy = *((volatile uint32 *) (SDRAM_BASE_ADDR | (0x32 << 13)));

   //**************SDRAM NORMAL command**************
    EMC_DYN_CTRL = 0x0000;       //Issue SDRAM norm command ; CLKOUT stop;All clock enables low
    EMC_DYN_CFG0 |= (1 << 19);   //Buffer enabled(B bit) for accesses to DCS0 chip
    for(i=0; i<10000; i++);
}

/******************************************************************************
* END OF FILE
******************************************************************************/
